package yartiss.engine.simulation.scheduling.policies.dp;

import java.util.SortedSet;

import yartiss.engine.simulation.IEnergyProfile;
import yartiss.engine.simulation.ISchedulingPolicy;
import yartiss.engine.simulation.Processor;
import yartiss.engine.simulation.events.EventGenerator;
import yartiss.engine.simulation.scheduling.policies.AbstractMultiProcSchedulingPolicy;
import yartiss.engine.simulation.system.ITask;
import yartiss.engine.simulation.system.ITaskSet;
import yartiss.engine.simulation.system.taskset.TaskSetFactory;

public class EDFMultiProcSchedulingPolicy extends AbstractMultiProcSchedulingPolicy{

	@Override
	public String getPolicyName() {
		return "EDF_multiproc";
	}

	@Override
	public ITaskSet createTaskSet() {
		return TaskSetFactory.getNewInstance("deadline");
	}
	
	@Override
	public ISchedulingPolicy newInstance(){
		return new EDFMultiProcSchedulingPolicy();
	}

	@Override
	public Processor[] chooseNextTasks(Processor[] processors,	ITaskSet taskSet, IEnergyProfile energyProfile, long date,EventGenerator evGen) {
		SortedSet<ITask> activeTasks = taskSet.getActiveTasks(date);
		
		int i=0;
		for (ITask task : activeTasks) {
			if(i<processors.length){
				long hlcet = energyProfile.howLongCanExecute(task);
				if (hlcet <= 0) {
					evGen.generateEvent("energy_failure", task, date, null);
					processors[i].setNextTask(null);
				}
				else {
					if (hlcet < task.getRemainingCost())
						evGen.generateEvent("check_energy_state", task, date + hlcet, null);
					processors[i].setNextTask(task);
				}
			}
			i++;
		}
		for(;i<processors.length; i++){
			processors[i].setNextTask(null);
		}
		return processors;
	}
}
